using System;
using System.Data;
using System.Xml;
using System.Runtime.Serialization;
using System.Collections;
using Widgetsphere.Core.Exceptions;
using Widgetsphere.Core.DataAccess;
using ACME.Northwind.Business;
using ACME.Northwind.Business.Objects;
using ACME.Northwind.Business.Rules;
using ACME.Northwind.Business.SelectCommands;
using System.Collections.Generic;

namespace ACME.Northwind.Domain.Objects
{
	/// <summary>
	/// This is an customizable extender for the domain class associated with the 'OrderDetail' object
	/// </summary>
	[Serializable()]
	partial class DomainOrderDetail : PersistableDomainObjectBase
	{
		#region Member Variables

		private const string TABLE_NAME = "OrderDetailCollection";
		internal DomainOrderDetailCollection ParentCol;

		#endregion

		#region Constructor

		internal DomainOrderDetail(DataRowBuilder rb) : base(rb) 
		{
			this.ParentCol = ((DomainOrderDetailCollection)(base.Table));
		}

		#endregion

		#region Properties

		internal OrderDetailPrimaryKey PrimaryKey
		{
			get { return new OrderDetailPrimaryKey(this.OrderId, this.ProductId); }
		}

		internal System.Single Discount
		{
			get
			{
				try
				{
					return ((System.Single)(base[this.ParentCol.DiscountColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  if (!base[this.ParentCol.DiscountColumn].Equals(value))
				{
					base[this.ParentCol.DiscountColumn] = value;
			  	wasSet = true;
				}

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderDetailCollection list = (OrderDetailCollection)this.ParentCol.SubDomain[Collections.OrderDetailCollection];
					OrderDetail item = list.GetItemByPK(this.OrderId, this.ProductId);
					if (item != null) item.Discount = value;
				}
			}
		}

		internal int OrderId
		{
			get
			{
				try
				{
					return ((int)(base[this.ParentCol.OrderIdColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
		}

		internal int ProductId
		{
			get
			{
				try
				{
					return ((int)(base[this.ParentCol.ProductIdColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
		}

		internal short Quantity
		{
			get
			{
				try
				{
					return ((short)(base[this.ParentCol.QuantityColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  if (!base[this.ParentCol.QuantityColumn].Equals(value))
				{
					base[this.ParentCol.QuantityColumn] = value;
			  	wasSet = true;
				}

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderDetailCollection list = (OrderDetailCollection)this.ParentCol.SubDomain[Collections.OrderDetailCollection];
					OrderDetail item = list.GetItemByPK(this.OrderId, this.ProductId);
					if (item != null) item.Quantity = value;
				}
			}
		}

		internal decimal UnitPrice
		{
			get
			{
				try
				{
					return ((decimal)(base[this.ParentCol.UnitPriceColumn]));
				}
				catch (InvalidCastException e) { throw new StrongTypingException(GlobalValues.ERROR_PROPERTY_NULL, e); }
			}
			set 
			{
				bool wasSet = false;
			  if (!base[this.ParentCol.UnitPriceColumn].Equals(value))
				{
					base[this.ParentCol.UnitPriceColumn] = value;
			  	wasSet = true;
				}

				if (wasSet && (this.ParentCol.TableName != TABLE_NAME) && this.ParentCol.SubDomain.Tables.Contains(TABLE_NAME))
				{
					OrderDetailCollection list = (OrderDetailCollection)this.ParentCol.SubDomain[Collections.OrderDetailCollection];
					OrderDetail item = list.GetItemByPK(this.OrderId, this.ProductId);
					if (item != null) item.UnitPrice = value;
				}
			}
		}

		internal virtual DomainOrder OrderItem
		{
			get { return (DomainOrder)base.GetParentRow(this.ParentCol.OrderOrderDetailRelation); }
			set
			{
				if (value != null)
				{
					DomainOrderCollection list = null;
					if (value.GetType() == typeof(DomainOrder))
						list = (DomainOrderCollection)this.ParentCol.SubDomain.GetDomainCollection(Collections.OrderCollection);
					bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
					this.ParentCol.SubDomain.EnforceConstraints = false;
					DomainOrder order = (DomainOrder)value;
					if(order.ParentCol != list)
					{
						this.ParentCol.SubDomain.Merge(new DataRow[] { order }, false, MissingSchemaAction.Error);
						order = list.GetOrder(order.OrderId);
					}
					base.SetParentRow(order, this.ParentCol.OrderOrderDetailRelation);
					this.ParentCol.SubDomain.EnsureParentRowsExist();				
					this.ParentCol.SubDomain.EnforceConstraints = oldEc;
				}
				else
				{
					if(this.ParentCol.OrderIdColumn.AllowDBNull)
					{
						base.SetNull(this.ParentCol.OrderIdColumn);
					}
					else
					{
						this.Delete();
					}
				}
			}
		}

		internal virtual DomainProduct ProductItem
		{
			get { return (DomainProduct)base.GetParentRow(this.ParentCol.ProductOrderDetailRelation); }
			set
			{
				if (value != null)
				{
					DomainProductCollection list = null;
					if (value.GetType() == typeof(DomainProduct))
						list = (DomainProductCollection)this.ParentCol.SubDomain.GetDomainCollection(Collections.ProductCollection);
					bool oldEc = this.ParentCol.SubDomain.EnforceConstraints;
					this.ParentCol.SubDomain.EnforceConstraints = false;
					DomainProduct product = (DomainProduct)value;
					if(product.ParentCol != list)
					{
						this.ParentCol.SubDomain.Merge(new DataRow[] { product }, false, MissingSchemaAction.Error);
						product = list.GetProduct(product.ProductId);
					}
					base.SetParentRow(product, this.ParentCol.ProductOrderDetailRelation);
					this.ParentCol.SubDomain.EnsureParentRowsExist();				
					this.ParentCol.SubDomain.EnforceConstraints = oldEc;
				}
				else
				{
					if(this.ParentCol.ProductIdColumn.AllowDBNull)
					{
						base.SetNull(this.ParentCol.ProductIdColumn);
					}
					else
					{
						this.Delete();
					}
				}
			}
		}

		#endregion

		#region Collection Operation Methods

		/// <summary>
		/// Serves as a hash function for this particular type.
		/// </summary>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public override bool Equals(object obj)
		{
			if (obj == null) return false;
			if (obj.GetType() != this.GetType()) return false;

			if ((this.RowState == DataRowState.Deleted) ||
				(((DataRow)obj).RowState == DataRowState.Deleted) ||
				(this.RowState == DataRowState.Detached) ||
				(((DataRow)obj).RowState == DataRowState.Detached))
				return false;

			return ((DomainOrderDetail)obj).PrimaryKey.Equals(this.PrimaryKey);
		}

		public override void Persist()
		{
			DomainHelper.PersistDomainObject(this, this.ParentCol.SubDomain, Collections.OrderDetailCollection, this.ParentCol.Modifier);
		}

		public override void Remove()
		{
			this.ParentCol.RemoveOrderDetail(this);
		}

		#endregion

		#region Relationship Methods
		internal virtual void ReleaseNonIdentifyingRelationships()
		{
		}

		#endregion
	}
}
